﻿#pragma once
#include <list>
#include <string>
#include <set>
#include <map>
#include <functional>

// 主力合约的收集，目标是收集活跃的主力合约，每个
#define Main_Symbol_Num 2
#define Symbol_Name_Len 15
#define Symbol_Name_Vec_Len 16
class MainSymbolGather
{
private:

	struct SymbolNameStr 
	{
		char BaseStr[Symbol_Name_Vec_Len];

		SymbolNameStr();
		SymbolNameStr(const std::string &pSymbol);
		bool operator<(const SymbolNameStr& rhs) const;
		bool operator == (const SymbolNameStr& rhs);
	};

	struct SymbolInfoData 
	{
		SymbolInfoData();
		SymbolNameStr SymbolName;
		float OpenInterest; // 持仓量
		time_t BeginTime;
		int MDRate; // 活跃次数
		bool FinishGathing;
	};

	MainSymbolGather();
	~MainSymbolGather();
public:
	static MainSymbolGather &Instance();
	// 设置取消订阅的回调
	void SetUnSubscribeFunc(std::function<void(const std::list<std::string> &pList)> pFunc){ m_unSubscribeFunc = pFunc; }
	// 得到今天的主力合约，如果今天已经过滤过主力合约了，那就返回所有的主力合约，否则返回所有的合约
	void GetToRegSymbols(std::list<std::string> &outList);

	// 判断合约是不是上期所或能源中心
	bool IsSHFEorINE(char pSymbol[81]);
	// 判断是否是主力合约
	bool IsMainSymbol(char pSymbol[81], float pOpenInterest, time_t pTime);
private:
	// 初始化
	void init();
	// 得到合约系列名称
	void getClassName(SymbolNameStr &outClass, char pSymbol[81]);
	// 检查主力合约
	inline bool checkMainSymbol(char pSymbol[81], float pOpenInterest, time_t pTime);

	// 所有合约
	std::set<std::string> m_allSymbols;
	// 上期所和能源所的合约品种 只有类型
	std::set<SymbolNameStr> m_SHFEorINESymbols;
	// 老的主力合约（今天之前的主力合约）
	std::set<SymbolNameStr> m_oldMainSymbols;
	// 新的主力合约（今天的主力合约）
	std::set<SymbolNameStr> m_newMainSymbols;
	// 具有订单的合约
	std::set<SymbolNameStr> m_orderSymbols;
	// 正在收集的主力合约<品种，合约的信息数据>
	std::map<SymbolNameStr, SymbolInfoData> m_gatheringMainSymbols;

	std::function<void(const std::list<std::string> &pList)> m_unSubscribeFunc;
};

